package com.yida.wy.basic.controller.common;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.PhoneUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.domain.R;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.CheckRemoteServiceResultUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.file.FileTypeUtils;
import com.yida.common.core.utils.file.MimeTypeUtils;
import com.yida.common.core.web.controller.BaseController;
import com.yida.common.core.web.domain.AjaxResult;
import com.yida.common.log.annotation.Log;
import com.yida.common.log.enums.BusinessType;
import com.yida.common.redis.service.RedisService;
import com.yida.system.api.RemoteSmsService;
import com.yida.system.api.domain.SysFile;
import com.yida.system.api.domain.SysSms;
import com.yida.wy.basic.domain.request.WyOwnerAttestSubmitRequest;
import com.yida.wy.basic.service.IWyOwnerAttestService;
import com.yida.wy.common.domain.WyBaseBuild;
import com.yida.wy.common.domain.WyBaseCommunity;
import com.yida.wy.common.domain.WyBaseHouse;
import com.yida.wy.common.domain.dto.WyBaseBuildSelectDTO;
import com.yida.wy.common.domain.dto.WyBaseCommunitySelectDTO;
import com.yida.wy.common.domain.dto.WyBaseHouseSelectDTO;
import com.yida.wy.common.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

import static com.yida.wy.common.domain.table.WyBaseBuildTableDef.WY_BASE_BUILD;
import static com.yida.wy.common.domain.table.WyBaseCommunityTableDef.WY_BASE_COMMUNITY;
import static com.yida.wy.common.domain.table.WyBaseHouseTableDef.WY_BASE_HOUSE;

/**
 * 基础数据查询模块
 *
 * @author hmh
 * @date 2022-11-15
 */
@RestController
@RequestMapping("/public")
@Api(tags = "对外开放的接口")
public class WyPublicController extends BaseController {
    @Resource
    private IWyBaseCommunityService communityService;

    @Resource
    private IWyBaseHouseService houseService;

    @Resource
    private IWyBaseBuildService buildService;

    @Resource
    private RedisService redisService;

    @Resource
    private RemoteSmsService remoteSmsService;

    @Resource
    private IWyFileService wyFileService;

    @Resource
    private IWyOwnerAttestService gwjOwnerAttestService;

    private final String GWJ_OWNER_ATTEST_SMS_KEY = "gwj_owner_attest";


    /**
     * 根据小区ID查询小区信息 lqq
     *
     * @param areaId 小区ID
     * @return /
     */
    @ApiOperation(value = "根据地区ID查询小区信息列表", response = WyBaseCommunitySelectDTO.class)
    @GetMapping("/communitySelect/{areaId}")
    public AjaxResult communitySelect(@PathVariable Long areaId) {
        List<WyBaseCommunity> communities = communityService.list(QueryWrapper.create().where(WY_BASE_COMMUNITY.AREA_ID.eq(areaId)));
        if (StringUtils.isNotEmpty(communities)) {
            return AjaxResult.success(BeanUtil.copyToList(communities, WyBaseCommunitySelectDTO.class));
        }
        return AjaxResult.success();
    }

    /**
     * 查询基础楼栋列表(选择楼栋) lqq
     *
     * @param communityId 请求参数
     * @return /
     */
    @ApiOperation(value = "根据小区ID查询基础楼栋列表", response = WyBaseBuildSelectDTO.class)
    @GetMapping("/buildSelect/{communityId}")
    public AjaxResult buildInfo(@PathVariable Long communityId) {
        List<WyBaseBuild> builds = buildService.list(QueryWrapper.create().where(WY_BASE_BUILD.COMMUNITY_ID.eq(communityId)));
        if (StringUtils.isNotEmpty(builds)) {
            return AjaxResult.success(BeanUtil.copyToList(builds, WyBaseBuildSelectDTO.class));
        }
        return AjaxResult.success();
    }

    /**
     * 根据小区ID查询房屋信息 lqq
     *
     * @param areaId 小区ID
     * @return /
     */
    @ApiOperation(value = "根据地区ID和楼栋标识码查询房屋信息列表", response = WyBaseHouseSelectDTO.class)
    @GetMapping("/houseSelect/{areaId}/{buildCode}")
    public AjaxResult houseSelect(@PathVariable("areaId") Long areaId, @PathVariable("buildCode") String buildCode) {
        List<WyBaseHouse> houses = houseService.list(QueryWrapper.create().where(WY_BASE_HOUSE.AREA_ID.eq(areaId).and(WY_BASE_HOUSE.BUILD_CODE.eq(buildCode))));
        if (StringUtils.isNotEmpty(houses)) {
            return AjaxResult.success(BeanUtil.copyToList(houses, WyBaseHouseSelectDTO.class));
        }
        return AjaxResult.success();
    }

    /**
     * 业主信息认证-提交认证资料
     *
     * @param request 请求参数
     * @return /
     */
    @ApiOperation(value = "业主信息认证-提交认证资料")
    @PostMapping("/ownerAttest/submit")
    @Log(title = "业主信息认证-提交", businessType = BusinessType.INSERT, systemName = "gwj")
    public AjaxResult submit(@Validated @RequestBody WyOwnerAttestSubmitRequest request) {
        // 验证短信
        String smsCode = redisService.getCacheObject(getSmsCacheKey(request.getOwnerPhone(), GWJ_OWNER_ATTEST_SMS_KEY));
        if (StringUtils.isBlank(smsCode)) {
            throw new ServiceException("验证码不存在，请重新获取");
        }
        if (!request.getSmsCode().equals(smsCode)) {
            throw new ServiceException("验证码错误");
        }
        // 校验手机格式
        if (!PhoneUtil.isPhone(request.getOwnerPhone())) {
            throw new ServiceException("提交失败,手机号码格式有误");
        }
        // 校验身份证格式
        if (StringUtils.isNotBlank(request.getCardNum()) && !IdcardUtil.isValidCard(request.getCardNum())) {
            throw new ServiceException("提交失败,身份证号码格式有误");
        }
        return toAjax(gwjOwnerAttestService.submit(request));
    }

    /**
     * 业主信息认证-身份证上传
     *
     * @param file 房产证、身份证
     * @return /
     */
    @Log(title = "业主信息认证-房产证、身份证上传", businessType = BusinessType.UPDATE, systemName = "gwj")
    @PostMapping(value = "/ownerAttest/upload", headers = "content-type=multipart/form-data")
    @ApiOperation(value = "业主信息认证-房产证、身份证上传", response = SysFile.class)
    public AjaxResult uploadFile(@RequestPart("file") MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return AjaxResult.error("上传图片失败,图片异常");
        }
        String extension = FileTypeUtils.getExtension(file);
        if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
            return AjaxResult.error("上传图片失败,图片格式不正确" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
        }
        SysFile sysFile = wyFileService.uploadFileDynamicLink(file, null, true);
        return AjaxResult.success("上传图片成功", sysFile);
    }

    /**
     * 业主信息认证-发送短信
     *
     * @param phoneNum 手机号码
     * @return /
     */
    @ApiOperation(value = "业主信息认证-发送短信")
    @PostMapping("/ownerAttest/sendSms/{phoneNum}")
    public AjaxResult sendSms(@PathVariable String phoneNum) {
        if (!PhoneUtil.isPhone(phoneNum)) {
            return AjaxResult.error("发送失败,手机号码格式有误");
        }
        // 发送短信
        R<SysSms> r = remoteSmsService.sendSmsByPhonenumber(new SysSms() {{
            setSmsType(1);
            setPhonenumber(phoneNum);
            setSms("短信");
            setSmsSource(GWJ_OWNER_ATTEST_SMS_KEY);
        }}, SecurityConstants.INNER);
        AjaxResult result = toAjax(!CheckRemoteServiceResultUtils.isCodeFail(r));
        if (StringUtils.isNotNull(r.getData())){
            result.put(AjaxResult.MSG_TAG,r.getData().getSms());
        }else {
            result.put(AjaxResult.MSG_TAG, r.getMsg());
        }
        return result;
    }

    /**
     * 拼接缓存key
     *
     * @param ownerPhone 电话
     * @param key        前缀
     * @return /
     */
    public String getSmsCacheKey(String ownerPhone, String key) {
        return CacheConstants.SMS_CODE_EXPIRATION_KEY + key + ":" + ownerPhone;
    }
}
